Function.RegisterNamespace("System.Xml");

System.Xml.XmlDocument=function(){
    
    //ctor
    function XmlDocument(){
        if(document.implementation&&document.implementation.hasFeature("XPath","3.0")){ 
            XMLDocument.prototype.selectNodes=selectNodes;
            Node.prototype.selectNodes=selectNodes;
            XMLDocument.prototype.selectSingleNode=selectSingleNode;
            Node.prototype.selectSingleNode=selectSingleNode;        
        }
    }
    XmlDocument.apply(this,arguments);
    
    // Public Methods
    this.GetDocument=function(xml){
        try{
            if(typeof(ActiveXObject)!="undefined"){
                var doc=getMSXMLDom();
                if(doc)doc.loadXML(xml);
                return doc.documentElement;
            }
            if(typeof(DOMParser)!="undefined")return new DOMParser().parseFromString(xml,"text/xml").documentElement;
            throw new Error("Unknown client.");
        }catch(e){
            throw new Error(String.Format("System.Xml.XmlDocument.GetDocument: an unhandled Exception occurred. {0}",e));
        }
    };
    
    this.GetXml=function(document){
        if(document==undefined||!document.documentElement)throw new Error("System.Xml.XmlDocument.GetXml: 'documentRoot' must be a valid XmlDocument.");
        try{
            if(typeof(XMLSerializer)!="undefined")return new XMLSerializer().serializeToString(document);
            if(typeof(document.xml)!="undefined")return document.xml;
            throw new Error("Unknown client.");
        }catch(e){
            throw new Error(String.Format("System.Xml.XmlDocument.GetXml: an unhandled Exception occurred. {0}",e));
        }
    };
    
    this.Transform=function(xml,xsl){
        try{
            var xmlRoot=this.GetDocument(xml);
            var xslRoot=this.GetDocument(xsl);
            if(xmlRoot.transformNode)return xmlRoot.transformNode(xslRoot);
            if(typeof(XSLTProcessor)!="undefined")return processorTransform(xmlRoot,xslRoot);
            throw new Error("Unknown client.");
        }catch(e){
            throw new Error(String.Format("System.Xml.XmlDocument.Transform: an unhandled Exception occurred. {0}",e));
        }
    };

    // Private Methods
    function getMSXMLDom(){
        var MSXmlDoms=["Msxml2.DOMDocument.6.0","Msxml2.DOMDocument.5.0","Msxml2.DOMDocument.4.0","Msxml2.DOMDocument.3.0","Msxml2.DOMDocument","Microsoft.XMLDOM"];
        for(var i=0;i<MSXmlDoms.length;i++){
            try{
                return new ActiveXObject(MSXmlDoms[i]);
            }catch(e){}
        }
        return null;
    }
    
    function processorTransform(xmlRoot,xslRoot){
        var processor=new XSLTProcessor();
        processor.importStylesheet(xslRoot);
        return processor.transformToDocument(xmlRoot);
    }

    function selectNodes(path,node){
        if(node)node=this;
        var doc=this.ownerDocument;
        var nsResolver=doc.createNSResolver(doc.documentElement);
        var snapshot=doc.evaluate(path,node,nsResolver,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
        var result=[];
        for(var i=0;i<snapshot.snapshotLength;i++)result.push(snapshot.snapshotItem(i));
        return result;
    } 

    function selectSingleNode(path,node){ 
        if(!node)node=this;
        return this.selectNodes(path,node)[0]||null;
    }
};